﻿using RMS.EF.Model;
using RMS.EF.Model.Common;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Dynamic;
using System.Text;
using System.Threading.Tasks;

namespace RMS.BLL
{
    public class MenuBll
    {

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="searchValue">搜索框</param>
        /// <param name="status">状态</param>
        /// <param name="type_m">菜单类型</param>
        /// <param name="programId">项目Id</param>
        /// <returns></returns>
        public List<RMS_Menu> GetBySearch(string searchValue, E_Status status, E_Type_Menu type_m, string programId)
        {
            List<RMS_Menu> result = new List<RMS_Menu>();
            using (var db = new RMSEntities())
            {
                var q = db.RMS_Menu.Where(p => p.Deleted == (int)E_Deleted.Normal);
                #region where
                if (!string.IsNullOrWhiteSpace(searchValue))
                {
                    q = q.Where(p => p.Name.Contains(searchValue) || p.Url.Contains(searchValue));
                }
                if (status != E_Status.All)
                {
                    q = q.Where(p => p.Status == (int)status);
                }
                if (type_m != E_Type_Menu.All)
                {
                    q = q.Where(p => p.Type == (int)type_m);
                }
                if (!string.IsNullOrWhiteSpace(programId))
                {
                    q = q.Where(p => p.ProgramId == programId);
                }
                #endregion
                #region order by
                q = q.OrderBy(p => p.Ordering);
                #endregion

                result = q.ToList();
            }
            return result;
        }
        /// <summary>
        /// 软删除
        /// </summary>
        /// <param name="id">数据Id字符串","分隔</param>
        /// <returns></returns>
        public CommonOutPutVm Delete(string id)
        {
            CommonOutPutVm result = new CommonOutPutVm();
            using (var db = new RMSEntities())
            {
                using (var tran = db.Database.BeginTransaction())
                {
                    try
                    {
                        db.Database.ExecuteSqlCommand("update RMS_Menu set Deleted=1 where Id in (" + id + ")");
                        db.SaveChanges();
                        result = DeleteSon(id, db);
                        if (!result.IsSuccess)
                        {
                            tran.Rollback();
                            result.Message = "Delete failed";
                        }
                        tran.Commit();
                    }
                    catch (Exception e)
                    {
                        tran.Rollback();
                        throw e;
                    }
                }
            }
            result.IsSuccess = true;
            result.Message = "Delete success";
            return result;
        }
        /// <summary>
        /// 根据Id获取未删除的实体
        /// </summary>
        /// <param name="id">Id主键</param>
        /// <returns></returns>
        public RMS_Menu GetById(string id)
        {
            RMS_Menu result = new RMS_Menu();
            using (var db = new RMSEntities())
            {
                result = db.RMS_Menu.AsNoTracking().FirstOrDefault(p => p.Id == id && p.Deleted == (int)E_Deleted.Normal);
            }
            return result;
        }
        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="model">编辑后的模型实体</param>
        /// <returns></returns>
        public CommonOutPutVm Edit(RMS_Menu model)
        {
            CommonOutPutVm result = new CommonOutPutVm();
            using (var db = new RMSEntities())
            {
                using (var tran = db.Database.BeginTransaction())
                {
                    try
                    {

                        bool exist = db.RMS_Menu.Any(p => p.Deleted == (int)E_Deleted.Normal && p.Id != model.Id && p.ParentId == model.ParentId && p.Url == model.Url && !string.IsNullOrEmpty(p.Url));
                        if (exist)
                            throw new Exception("This menu / function already exists in the directory");
                        db.RMS_Menu.Attach(model);
                        db.Entry(model).State = string.IsNullOrWhiteSpace(model.Id) ? EntityState.Modified : EntityState.Added;
                        int row = db.SaveChanges();
                        if (row != 1)
                            throw new Exception("Save failed");
                        #region 批量禁用
                        if (model.Status == (int)E_Status.Disable)
                        {
                            result = DisableSon(model.Id.ToString(), db);
                            if (!result.IsSuccess)
                            {
                                tran.Rollback();
                                result.Message = "Delete failed";
                            }
                        }
                        #endregion
                        tran.Commit();
                    }
                    catch (Exception e)
                    {
                        tran.Rollback();
                        throw e;
                    }
                }
            }
            result.IsSuccess = true;
            result.Message = "Save success";
            return result;
        }
        /// <summary>
        /// 根据管理员Id和项目Id获取菜单列表
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="programId">项目Id</param>
        /// <returns></returns>
        public virtual List<RMS_Menu> GetMenuByManagerId(string userId, string programId)
        {
            using (var db = new RMSEntities())
            {
                string sql = @"
select m.* from RMS_Menu m 
left join RMS_Program p on m.ProgramId=p.Id and p.Deleted=0 and p.[Status]=1
join (
select distinct rm.MenuId from RMS_Role_Menu rm 
left join RMS_Role r on r.Id=rm.RoleId and r.Deleted=0 and r.[Status]=1
left join RMS_User_Role ur on ur.RoleId=r.Id and ur.Deleted=0
left join RMS_User u on u.Id=ur.UserId and u.Deleted=0 and u.[Status]=1
where rm.Deleted=0 and u.Id=@userId
) t on t.MenuId=m.Id
where m.Deleted=0 and m.[Status]=1 and p.Id=@programId
";
                var list = db.Database.SqlQuery<RMS_Menu>(sql
                    , new SqlParameter("@userId", userId)
                    , new SqlParameter("@programId", programId)).ToList();
                return list;
            }
        }
        /// <summary>
        /// 级联删除
        /// </summary>
        /// <param name="id">Id串</param>
        /// <param name="db">数据实体</param>
        /// <returns></returns>
        private CommonOutPutVm DeleteSon(string id, RMSEntities db)
        {
            CommonOutPutVm result = new CommonOutPutVm();
            var sons = db.Database.SqlQuery<RMS_Menu>("select * from RMS_Menu where Deleted=0 and ParentId in (" + id + ")").ToList();
            if (sons.Count > 0)
            {
                List<string> sonsids = (from s in sons select s.Id).ToList();
                string sonsidstr = string.Join(",", sonsids);
                result = DeleteSon(sonsidstr, db);
                if (result.IsSuccess)
                {
                    db.Database.ExecuteSqlCommand("update RMS_Menu set Deleted=1 where Deleted=0 and ParentId in (" + id + ")");
                    db.SaveChanges();
                }
            }
            result.IsSuccess = true;
            return result;
        }

        /// <summary>
        /// 级联禁用
        /// </summary>
        /// <param name="id">Id串</param>
        /// <param name="db">数据实体</param>
        /// <returns></returns>
        private CommonOutPutVm DisableSon(string id, RMSEntities db)
        {
            CommonOutPutVm result = new CommonOutPutVm();
            var sons = db.Database.SqlQuery<RMS_Menu>("select * from RMS_Menu where Deleted=0 and [Status]=1 and ParentId in (" + id + ")").ToList();
            if (sons.Count > 0)
            {
                List<string> sonsids = (from s in sons select s.Id).ToList();
                string sonsidstr = string.Join(",", sonsids);
                result = DisableSon(sonsidstr, db);
                if (result.IsSuccess)
                {
                    db.Database.ExecuteSqlCommand("update RMS_Menu set [Status]=0 where Deleted=0 and [Status]=1 and ParentId in (" + id + ")");
                    db.SaveChanges();
                }
            }
            result.IsSuccess = true;
            return result;
        }
    }
}
